#ifndef _TBHASHMAP_H_
#define _TBHASHMAP_H_

#include "TBHashManager.h"

#define TB_HASHMAP_USEMD5

namespace tb
{

	template<typename T>
	class HashMap
	{

		typedef unsigned char KeyValue;
	
	public:

		friend struct BinaryLeaf;
	
		HashMap();
		~HashMap();

		HashMap<T>& Insert(const char* a_Key, T* a_Value);

		T* Find(const char* a_Key);
	
	private:

		struct BinaryLeaf
		{

			BinaryLeaf()
			{
				key = 0;
				key_original = NULL;
				offset = 0;
				index = 0;
				left = right = 0;
				value = NULL;
			}
			~BinaryLeaf()
			{
				if (key_original) { delete key_original; }
			}

			KeyValue key;
			char* key_original;
			unsigned int offset;
			unsigned int index;
			unsigned int left;
			unsigned int right;
			T* value;

		};

		void AddKey(const char* a_Key)
		{
			m_Keys[m_KeysFilled] = new char[strlen(a_Key)];
			memset(m_Keys[m_KeysFilled], 0, strlen(a_Key));
			strcpy(m_Keys[m_KeysFilled], a_Key);

			m_KeysFilled++;
		}

		unsigned int _EmptyLeaf();
		void _InsertKey(BinaryLeaf* a_Target, const KeyValue* a_Key, unsigned int a_Offset, unsigned int a_Length, T* a_Value);
		T* _Find(BinaryLeaf* a_Target, const KeyValue* a_Key, unsigned int a_Offset, unsigned int a_Length);

		BinaryLeaf* m_TreeRoot;

		char** m_Keys;
		unsigned int m_KeysFilled;

		BinaryLeaf** m_Nodes;
		unsigned int m_NodesFilled, m_NodesMaximum;

		T** m_Data;
	
	}; // class HashMap

}; // namespace tb

#include "TBHashMap.inl"
	
#endif